#include <iostream>
#include <string>
using namespace std;

#include <SDL.h>
#include <SDL_test.h>
#include <SDL_ttf.h>
#include <SDL_image.h>

SDL_Window* wnd = 0;
SDL_Renderer* render = 0;
SDL_Texture* texture = 0;
TTF_Font *font = 0;
struct sedit* edit = 0;

void Log(string str)
{
    cout << str << endl;
}
//-----------
void clear()
{
    if (edit){
        delete edit;
        edit = 0 ;
    }
    if (texture){
		SDL_DestroyTexture(texture);
		texture = 0;
	}
    if (render){
		SDL_DestroyRenderer(render);
		render = 0;
	}
    if (font){
        TTF_CloseFont(font);
        font = 0;
    }
    TTF_Quit();
    IMG_Quit();
    SDL_Quit();
}

void Failed(string str = "")
{
    if (!str.empty()){
        Log(str);
    }
    clear();
    exit(-1);
}

void Success(string str = "")
{
    if (!str.empty()){
        Log(str);
    }
    clear();
    exit(0);
}

void SetColor(SDL_Color* col, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
	col->a = a;
	col->r = r;
	col->g = g;
	col->b = b;
}

void SetRect(SDL_Rect* rect, int x, int y, int w, int h)
{
	rect->x = x;
	rect->y = y;
	rect->w = w;
	rect->h = h;
}

void RenderText(SDL_Renderer* render, string text,SDL_Rect& rc, TTF_Font *font, SDL_Color& color)
{
    if (text.empty()) return;
    //SDL_Surface *temp = TTF_RenderUTF8_Blended(font,text.c_str(),color);
    SDL_Surface *temp = TTF_RenderUTF8_Blended_Wrapped(font,text.c_str(),color,rc.w);

    int w = SDL_min(rc.w,temp->w);
    int h = SDL_min(rc.h,temp->h);
    SDL_Rect rcdst,rcsrc;
    SetRect(&rcsrc,0,0,w,h);
    SetRect(&rcdst,rc.x,rc.y,rc.x+w,rc.y+h);
    
    TTF_SizeUTF8(font,text.c_str(),&w,&h);
    SDL_Rect pos;
    pos.x=rc.x + w;
    pos.y=rc.y + h;
    pos.w=pos.x+w;
    pos.h=pos.y+h;
    SDL_SetTextInputRect(&pos);

    SDL_Texture* texture = SDL_CreateTextureFromSurface(render,temp);
    SDL_assert(texture);

    SDL_RenderCopy(render, texture,&rcsrc,&rcdst);

    SDL_FreeSurface(temp);
    SDL_DestroyTexture(texture);
}

void RenderAll();

struct sedit
{
    SDL_Texture* texture;
    SDL_Color color;
    string text;
    SDL_Rect rc;
    void Init(int x, int y, int w, int h,SDL_Color& color)
    {
        texture = 0;
        SetRect(&rc,x,y,w,h);
        this->color = color;
        text.clear();
    }
    bool Update(SDL_Event& evt)
    {
        bool handled = false;
        switch(evt.type){
        case SDL_TEXTINPUT:
            Log("edit text input.");
            text = text + evt.text.text;
            handled = true;
            RenderAll();
            break;
        case SDL_TEXTEDITING:
            handled = true;
            break;
        case SDL_MOUSEBUTTONDOWN:
            if (IsInRc(evt.button.x, evt.button.y)){
                //begin edit
                Log("begine edit");
                SDL_SetTextInputRect(&rc);
                SDL_StartTextInput();
                handled = true;
            }else{
                //end edit
                Log("end edit,clear edit.");
                SDL_StopTextInput();
                text.clear();
                RenderAll();
            }
            break;
        default:
            break;
        }
        return handled;
    }
    void Render(SDL_Renderer* render)
    {
        RenderText(render,text,rc,font,color);

        SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
        SDL_RenderDrawRect(render, &rc);
    }
    bool IsInRc(int x,int y)
    {
        if (x<rc.x || x>rc.x+rc.w) return false;
        if (y<rc.y || y>rc.y+rc.h) return false;
        return true;
    }
};

void RenderAll()
{
    SDL_RenderClear(render);
    SDL_RenderCopy(render, texture, 0, 0);
    edit->Render(render);
    SDL_RenderPresent(render);
}

int main(int argc, char** argv)
{
    Log("hello world.");

    SDL_Init(SDL_INIT_EVERYTHING);
    IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP);
    TTF_Init();

    wnd=SDL_CreateWindow("sdl-test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
		480, 640, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
    if (!wnd) Failed("create window failed.");
    render = SDL_CreateRenderer(wnd, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (!render) Failed("create render failed.");
    texture = IMG_LoadTexture(render, "img/26.jpg");
    if (!texture) Failed("create texture failed.");

    font = TTF_OpenFont("font/simfang.ttf",16);
    if (!font) Failed("create font failed.");

    SDL_Color color;
    edit = new sedit;
    SetColor(&color,255,255,0,255);
    edit->Init(0,0,479,200,color);

    SDL_Event evt;
    while (true)
    {
        SDL_WaitEvent(&evt);

        if (edit->Update(evt)) continue;

        switch (evt.type){
        case SDL_QUIT:
            Success("run test_sdl success.done");
            break;
        case SDL_WINDOWEVENT:
			if (SDL_WINDOWEVENT_EXPOSED == evt.window.event){
                RenderAll();
            }
            break;
        default:
            break;
        }
    }

    clear();
    return 0;
}
